<?
class nodes
{
    var $nodes=array();
    var $path=array();
    var $id;
    public function __construct() {
        
    }

    // Create new node
    static public function create($data)
    {
        global $dbdefault;
       if (empty($data['node_name'])){
            return array('success'=>FALSE,'error'=>'Category name must not be empty!');
       }                
       $query = sprintf("INSERT INTO ".TB_nodes." (node_name,node_u_name,parent_id,node_priority) VALUES (%s,%s,%d,%d)",
                        quote_smart($data['node_name']),quote_smart($data['node_u_name']),quote_smart($data['parent_id']),quote_smart($data['node_priority'])
                     );
       mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());       
       return array('success'=>TRUE,'node_id'=>mysql_insert_id());
    }

    // Update node
    static public function update($data)
    {
        global $dbdefault;
       $query=sprintf("UPDATE ".TB_nodes."
                        SET node_name=%s,node_u_name=%s,parent_id=%d,node_priority=%d  WHERE node_id=%d",
                        quote_smart($data['node_name']),qs($data['node_u_name']),quote_smart($data['parent_id']),
			quote_smart($data['node_priority']),quote_smart($data['node_id'])
                        );
       mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());
       return array('success'=>TRUE);
    }

    static public function get_node($node_id){
       global $dbdefault;
        $query = sprintf('SELECT * FROM '.TB_nodes.' WHERE node_id=%d', $node_id);
       $res = mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());
       if ($data=mysql_fetch_assoc($res)){
           return array('success'=>TRUE,'data'=>$data);           
       }else{
           return array('success'=>FALSE,'error'=>'Category does not exist!');
       }
    }
    
    // Return the tree structure of nodes from the current id
    // Current id = 0 mean open the whole structures
    public function open_nodes_tree($id,$level=1,$itt=0)
    {
       $cats=array();
       $descendants=$nodes[$id]['descendants']=$this->get_descendants($id);
       $cats[$itt]=array('id'=>$id,'level'=>$level,'descendants'=>$descendants);
       $children=$this->get_children($id);
       foreach ($children as $child_id)
       {
          $child=$this->open_nodes_tree($child_id,$level+1,$itt+1);
          $cats=array_merge($cats,$child);
       }
       return $cats;
    }


    // Return the tree structure of nodes from the current id
    // Current id = 0 mean open the whole structures$le
    public function browse_nodes_tree($id)
    {
       $path=$this->get_path($id);
       $this->path=$path;
       $depth=count($path);
       if (!count($this->nodes)) $this->get_full_list();
       $cats=$this->nodes;
       $full_list=$this->open_nodes_tree(0,0);
       foreach ($full_list as $item)
       {
          $id=$item['id'];
          if (in_array($cats[$id]['parent_id'],$path))
          {
             $return_arr[$id]=$item;
          }
       }
       return $return_arr;
    }

    // Get full lists of nodes
    public function get_full_list(){
       	global $dbdefault;
        $nodes=array();
       	$root=array('name'=>'root','u_name'=>'root','parent_id'=>-1);
       	$nodes[0]=$root;
       	$query="SELECT * FROM ".TB_nodes." ORDER BY node_priority";
       	$result=mysql_query($query,$dbdefault) or die(mysql_error());
       	while ($array=mysql_fetch_assoc($result)){
            $id=$array['node_id'];
            $nodes[$id]=$array;
            $nodes[$id]['name']=$array['node_name'];
            $nodes[$id]['u_name']=$array['node_u_name'];
            $nodes[$id]['parent_id']=$array['parent_id'];
	}
       	$this->nodes=$nodes;
        
        foreach($nodes as $id=>$c){
            $nodes[$id]['descendants']=$this->get_descendants($id);      
        }
       	$this->nodes=$nodes;
    }

    /* Navigation functions*/
    //Return the parent_id of current id
    public function get_parent($id)
    {
       if (!count($this->nodes)) $this->get_full_list();
       if (array_key_exists($id,$this->nodes))
           return $this->nodes[$id]['parent_id'];
       else
           return -1;
    }

    //Return the list(array) of children nodes id
    function get_children($id){
       	if (!count($this->nodes)) $this->get_full_list();
       	$children=array();
       	foreach ($this->nodes as $c_id=>$node){
           if ($node['parent_id']==$id) array_push($children,$c_id);
       	}
       	return $children;
    }

    //Return the list(array) of descendants nodes id
    public function get_descendants($id){
       	$children=$this->get_children($id);
       	foreach ($children as $children_id){
            $grandchildren=$this->get_descendants($children_id);
            $children=array_merge($children,$grandchildren);
       	}
       	return $children;
    }

    //Return the root node from current node (id)
    public function get_root($id)
    {
       $pid=$this->get_parent($id);
       if ($pid==0)
          return $id;
       else
          return $this->get_root($pid);
    }

    //Return the nodes having same parent as current nodes
    function get_siblings($id)
    {
       $parent_id=$this->get_parent($id);
       $chilren=$this->get_children($parent_id);
       $siblings=array();
       foreach ($chilren as $child_id)
       {
          if ($child_id!=$id)
          array_push($siblings,$child_id);
       }
       return $siblings;
    }


    //Return the path from root to current node (id)
    function get_path($id)
    {
       $parent_id=$this->get_parent($id);
       if ($parent_id>=0)
       {
          $array=$this->get_path($parent_id);
          array_push($array,$id);
       }
       else
       {
          $array = array($id);
       }
       return $array;
    }


}

?>